/*
* Copyright 2011 Pavel Kozhin 
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed  under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*
* Author: Pavel Kozhin.
*/
package org.etherframework.controller
{
	import org.etherframework.IEther;
	import org.etherframework.common.ICancelable;
	import org.etherframework.common.command.ICommand;
	import org.etherframework.common.dependency.IEtherChild;
	import org.etherframework.common.dependency.IEtherOwner;
	import org.etherframework.core.common.ether_internal;
	import org.etherframework.core.context.Context;
	import org.etherframework.core.context.IContexts;
	import org.etherframework.core.context.IContextual;
	import org.etherframework.core.context.IContextualCreator;
	
	use namespace ether_internal;
	
	[Exclude(kind="method", name="childAdd")]
	[Exclude(kind="method", name="childRemove")]
	[Exclude(kind="method", name="create")]
	[Exclude(kind="method", name="dispose")]
	
	public class Controller implements IController, IContextualCreator, IEtherOwner
	{
		private var _ether:IEther;
		private var _contexts:IContexts;
		private var _commands:Vector.<ReactiveCommand>;
		
		ether_internal final function __init(ether:IEther, contexts:IContexts):void
		{
			_ether = ether;
			_contexts = contexts;
			_commands = new Vector.<ReactiveCommand>();
		}
		
		public function contextual(context:Context, type:Class):IContextual
		{
			return _contexts.contextual(context, type, this);
		}
		
		public function create(context:Context, type:Class):IContextual
		{
			return _ether.contextual(context).dependencies.getInstance(type) as IContextual;
		}
		
		public function dispose():void
		{
			_contexts.dispose(this);
		}
		
		public function cancelAll():void
		{
			for (var i:int = 0; i < _commands.length; i++) 
			{
				if (_commands[i] is ICancelable)
				{
					(_commands[i] as ICancelable).cancel();
				}
			}
		}
		
		public final function childAdd(value:IEtherChild):void
		{
			if (value is ReactiveCommand)
			{
				_commands.push(value as ReactiveCommand);
			}
		}
		
		public final function childRemove(value:IEtherChild):void
		{
			if (value is ReactiveCommand && _commands.indexOf(value) != -1)
			{
				_commands.splice(_commands.indexOf(value), 1);
			}
		}
		
		protected function command(type:Class):ICommand
		{
			return ether.dependencies.getInstance(type) as ICommand;
		}
		
		public function get context():Context { return _ether.context; }
		public function get ether():IEther { return _ether; }
	}
}